package mysql

import (
	"DouBan/model"
	logger2 "DouBan/utils/logger"
	"database/sql"
	"github.com/BurntSushi/toml"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"math/rand"
	"time"
)

type __dbConfigMysql struct {
	MasterDsn        string   `toml:"master_dsn"`
	SlaveDsnList     []string `toml:"slave_dsn_list"`
	MaxConnAliveTime int      `toml:"max_conn_alive_time"`
	MaxConnIdleNum   int      `toml:"max_conn_idle_num"`
	MaxConnOpenNum   int      `toml:"max_conn_open_num"`
}

var (
	dbConfigMysql     *__dbConfigMysql
	err               error
	masterDb          *gorm.DB
	masterSqlDb       *sql.DB
	slaveDb           *gorm.DB
	slaveSqlDb        *sql.DB
	slaveDbList       = make([]*gorm.DB, 0)
	slaveDbListLength int
)

func (d *__dbConfigMysql) parseConfig(configPath string) error {
	_, err = toml.DecodeFile(configPath, d)
	return err
}

func MasterDb() *gorm.DB {
	return masterDb
}

func SlaveDb() *gorm.DB {
	return slaveDbList[rand.Intn(slaveDbListLength)]
}

func Init(configPath string) error {
	dbConfigMysql = new(__dbConfigMysql)
	if err = dbConfigMysql.parseConfig(configPath); err != nil {
		return err
	}
	newLogger := logger.New(logger2.GetSqlLog(), logger.Config{
		SlowThreshold:             0,
		Colorful:                  true,
		IgnoreRecordNotFoundError: true,
		LogLevel:                  logger.Info,
	})
	//初始化master
	masterDb, err = gorm.Open(mysql.Open(dbConfigMysql.MasterDsn), &gorm.Config{Logger: newLogger})
	if err != nil {
		return err
	}
	masterSqlDb, _ = masterDb.DB()
	masterSqlDb.SetConnMaxLifetime(time.Duration(dbConfigMysql.MaxConnAliveTime) * time.Second)
	masterSqlDb.SetMaxOpenConns(dbConfigMysql.MaxConnOpenNum)
	masterSqlDb.SetMaxIdleConns(dbConfigMysql.MaxConnIdleNum)
	if err = masterDb.AutoMigrate(model.GetObjects()...); err != nil {
		return err
	}
	//初始化slave
	for _, slaveDsn := range dbConfigMysql.SlaveDsnList {
		slaveDb, err = gorm.Open(mysql.Open(slaveDsn), &gorm.Config{Logger: newLogger})
		if err != nil {
			return err
		}
		slaveDbList = append(slaveDbList, slaveDb)
		slaveSqlDb, _ = slaveDb.DB()
		slaveSqlDb.SetConnMaxLifetime(time.Duration(dbConfigMysql.MaxConnAliveTime) * time.Second)
		slaveSqlDb.SetMaxOpenConns(dbConfigMysql.MaxConnOpenNum)
		slaveSqlDb.SetMaxIdleConns(dbConfigMysql.MaxConnIdleNum)
		if err = slaveDb.AutoMigrate(model.GetObjects()...); err != nil {
			return err
		}
	}
	slaveDbListLength = len(slaveDbList)
	return nil
}

func Exit() {
	//_ = masterSqlDb.Close()
	//_ = slaveSqlDb.Close()
}
